package com.intretech.umsin.oss.util.ftppool;


import com.intretech.umsin.oss.config.FtpClientProperties;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

/**
 * @version V1.0
 * @ClassName: FtpClientFactory
 * @Description: FtpClientFactory 服务实现
 * @author: 李启联
 * @date: 2022-04-25 14:50
 * @Copyright: Copyright (c) 2022
 */
public class FtpClientFactory extends BasePooledObjectFactory<FTPClient> {

    private static final Logger log = LoggerFactory.getLogger(FtpClientFactory.class);

    private FtpClientProperties config;

    public FtpClientProperties getConfig() {
        return config;
    }

    public FtpClientFactory(FtpClientProperties config) {
        this.config = config;
    }

    /**
     * 创建FtpClient对象
     */
    @Override
    public FTPClient create() throws Exception{
        FTPClient ftpClient = new FTPClient();
        ftpClient.setConnectTimeout(config.getConnectTimeout());
        ftpClient.setControlKeepAliveTimeout(config.getKeepAliveTimeout());
        if (config.isPassiveMode()) {
            ftpClient.enterLocalPassiveMode();
        }

        try {
            log.info("连接ftp服务器:" +config.getHost()+":"+config.getPort());
            ftpClient.connect(config.getHost(), config.getPort());

            int replyCode = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(replyCode)) {
                ftpClient.disconnect();
                log.error("FTP服务器 拒绝连接");
                return null;
            }

            if (!ftpClient.login(config.getUsername(), config.getPassword())) {
                log.error("ftpClient登录失败!");
                throw new Exception("ftpClient登录失败! userName:"+ config.getUsername() + ", password:" + config.getPassword());
            }

            ftpClient.setBufferSize(config.getBufferSize());
            ftpClient.setFileType(config.getTransferFileType());
            ftpClient.setUseEPSVwithIPv4(config.isUseEPSVwithIPv4());
            ftpClient.setControlEncoding(config.getEncoding());
            ftpClient.setDataTimeout(config.getDataTimeout());

            Boolean isWorkDirNotEmpty = StringUtils.isNotEmpty(config.getWorkDir())?"/".equals(config.getWorkDir()):false;
            if (isWorkDirNotEmpty) {
                ftpClient.changeWorkingDirectory(config.getWorkDir());
            }
        } catch (IOException e) {
            log.error("FTP连接失败：", e);
        }
        return ftpClient;
    }

    /**
     * 用PooledObject封装对象放入池中
     */
    @Override
    public PooledObject<FTPClient> wrap(FTPClient ftpClient) {
        return new DefaultPooledObject<FTPClient>(ftpClient);
    }

    /**
     * 销毁FtpClient对象
     */
    @Override
    public void destroyObject(PooledObject<FTPClient> ftpPooled) throws Exception {
        if (ftpPooled == null) {
            return;
        }
        FTPClient ftpClient = ftpPooled.getObject();
        ftpClient.logout();
        super.destroyObject(ftpPooled);
    }

    /**
     * 验证FtpClient对象
     */
    @Override
    public boolean validateObject(PooledObject<FTPClient> ftpPooled) {
        try {
            FTPClient ftpClient = ftpPooled.getObject();
            return ftpClient.sendNoOp();
        } catch (IOException e) {
            log.error("failed to validate client: {}", e);
        }
        return false;
    }

}
